package com.example.LibrarySystem.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.example.LibrarySystem.Exception.ServiceException;
import com.example.LibrarySystem.mapper.BookMapper;
import com.example.LibrarySystem.mapper.ClassesMapper;
import com.example.LibrarySystem.mapper.FilesMapper;
import com.example.LibrarySystem.mapper.UserMapper;
import com.example.LibrarySystem.pojo.Book;
import com.example.LibrarySystem.pojo.Classes;
import com.example.LibrarySystem.pojo.User;
import com.example.LibrarySystem.response.Result;
import com.example.LibrarySystem.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

@RestController
@RequestMapping("/files")
public class FileController {

    @Autowired
    private FileService fileService;

    @Autowired
    private FilesMapper filesMapper;

    @Autowired
    private ClassesMapper classesMapper;

    @Autowired
    private BookMapper bookMapper;

    @Autowired
    private UserMapper userMapper;

    private String[] strings = {"正在借阅", "正常还书", "延迟还书", "破损还书", "其他"};

    /**
     * 文件上传
     *
     * @param file
     */
    @PostMapping("/upload")
    public Result upload(@RequestBody MultipartFile file) throws Exception {
        Result result = new Result();
        String res = fileService.upload(file);
        result.setMsg("上传成功");
        result.setStatus(200);
        result.put("uuid", res);
        return result;
    }

    /**
     * 文件下载
     */
    @GetMapping("/{uuid}")
    public void download(@PathVariable String uuid, HttpServletResponse httpServletResponse) throws IOException {
        String[] strings = fileService.getFileAddress(uuid);

        File uploadFile = new File(strings[0] + strings[1]);

        //设置格式 以流的形式传输 filename=设置返回文件名字类型
        httpServletResponse.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(uuid, "UTF-8") + StrUtil.DOT + strings[1]);
        httpServletResponse.setContentType("application/octet-stream");

        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        // 读取数据
        outputStream.write(FileUtil.readBytes(uploadFile));
        outputStream.flush();
        outputStream.close();
    }

    /**
     * 文件预览
     */
    @GetMapping("/shows/{uuid}")
    public void preview(@PathVariable String uuid, HttpServletResponse httpServletResponse) throws IOException {
        String[] strings = fileService.getFileAddress(uuid);
        File uploadFile = new File(strings[0] + strings[1]);
        httpServletResponse.setContentType("text/html;charset=UTF-8");
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        //读取数据
        outputStream.write(FileUtil.readBytes(uploadFile));
        outputStream.flush();
        outputStream.close();
    }

    /**
     * excel导入
     *
     * @param table 哪张表
     */
    @PostMapping("/import/{table}")
    public Result excelImport(@RequestBody MultipartFile file, @PathVariable String table) throws Exception {

        System.out.println("添加到" + table + "表");

        try {
            InputStream inputStream = file.getInputStream();
            ExcelReader reader = ExcelUtil.getReader(inputStream);
            List<Map<String, Object>> maps = reader.readAll();


            for (Map<String, Object> map : maps) {

                if ("users".equals(table)) {
                    map.put("creation_time", new Date());
                    map.put("password", DigestUtil.md5Hex(map.get("password") == "" || map.get("password") == null ? "123456" : (String) map.get("password")));
                }


//            System.out.println("修改前"+obj);
                map.put("id", null);
//            System.out.println("修改后"+obj);
//            System.out.println()
                filesMapper.insertAllByMap(map, table);
            }
            return new Result("导入成功", 200);
        } catch (Exception e) {
            throw new ServiceException("-1", "导入失败请检查数据库列名是否正确");
        }
    }


    /**
     * 导出
     *
     * @param table               哪张表
     * @param httpServletResponse
     * @return
     * @throws Exception
     */
    @GetMapping("/export/{table}")
    public void export(@PathVariable String table, HttpServletResponse httpServletResponse) throws Exception {
        List<Map<String, Object>> maps = filesMapper.exportByTable(table);
//        for(Map<String, Object> map : maps){
//            System.out.println(map);
//        }

        if ("users".equals(table)) {
            for (Map<String, Object> map : maps) {
                Classes classes = classesMapper.selectById((int) map.get("class_id"));
                map.put("className", classes.getName());
                map.remove("password");
                map.remove("class_id");
            }
        }

        if ("borrowing".equals(table)) {
            for (Map<String, Object> map : maps) {
                map.put("status", strings[(int) map.getOrDefault("status", 4)]);

                Book book = bookMapper.selectById((int) map.get("book_id"));
                map.put("bookName", book.getName());
                User user = userMapper.selectById((int) map.get("user_id"));
                map.put("userSno", user.getSno());
                map.put("userName", user.getName());
                map.remove("book_id");
                map.remove("user_id");
            }
        }

        // 创建excel读取对象
        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 写到excel读取对象 放到内存中
        writer.write(maps, true);

        //设置浏览器响应形式
        String name = URLEncoder.encode(table + "表", "UTF-8");
        httpServletResponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + name + ".xlsx");

        //创建输出流
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        //将内存中的数据刷新到输出流中去
        writer.flush(outputStream, true);
        outputStream.close();
        writer.close();
    }

    /**
     * 获取导入模板
     */
    @GetMapping("/template/{table}")
    public void getTableTemplateByColumn(@PathVariable String table, HttpServletResponse httpServletResponse) throws IOException {
        List<Map<String, Object>> tableTemplateByColumn = filesMapper.getTableTemplateByColumn(table);
        List<Map<String, Object>> templates = new ArrayList<>();
        Map<String, Object> template = new HashMap<>();
        for (Map<String, Object> map : tableTemplateByColumn) {
            Set<Map.Entry<String, Object>> entries = map.entrySet();
            for (Map.Entry<String, Object> entrie : entries) {
                template.put((String) entrie.getValue(), "");
            }
        }

//        if("users".equals(table)){
//            template.put("classId选择",);
//        }

//        System.out.println(template);
        templates.add(template);

        // 创建excel读取对象
        ExcelWriter writer = ExcelUtil.getWriter(true);
        // 写到excel读取对象 放到内存中
        writer.write(templates, true);

        //设置浏览器响应形式
        String name = URLEncoder.encode(table + "表导入模板", "UTF-8");
        httpServletResponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        httpServletResponse.setHeader("Content-Disposition", "attachment;filename=" + name + ".xlsx");

        //创建输出流
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        //将内存中的数据刷新到输出流中去
        writer.flush(outputStream, true);
        outputStream.close();
        writer.close();
    }
}
